#ifndef __BASIC_ORAC_H__
#define __BASIC_ORAC_H__

#include <basic/misc.h>

__BEGIN_DECLS

#define ORA_OK						0
#define ORA_ERROR					-10000
#define ORA_COL_NOT_SUPPORTED		-10001
#define ORA_BIND_NUM_DISCORD        -10002
#define ORA_NO_DATA_FOUND			1403
#define ORA_UNIQUE_VIOLATE			-1

#define ORAC_DEFINE_MAX_NUM         50

#define ORAC_BIND_CHAR(_bind, _index, _var)                     \
do                                                              \
{                                                               \
    (_bind)->vars[_index]=(char *)malloc(strlen(_var)+1);       \
    strcpy((_bind)->vars[_index], _var);                        \
    trim_tail_space_notnull((_bind)->vars[_index]);             \
} while(0)

#define ORAC_BIND_INT(_bind, _index, _var)                      \
do                                                              \
{                                                               \
    (_bind)->vars[_index]=                                      \
        (char *)malloc(SHORT_NUMBER_SIZE+1);                    \
    sprintf((_bind)->vars[_index], SHORT_NUMBER_FMT, _var);     \
} while(0)

#define ORAC_BIND_LONG(_bind, _index, _var)                     \
do                                                              \
{                                                               \
    (_bind)->vars[_index]=                                      \
        (char *)malloc(LONG_NUMBER_FMT+1);                      \
    sprintf((_bind)->vars[_index], LONG_NUMBER_FMT, _var);      \
} while(0)

#define ORAC_BIND_LLONG(_bind, _index, _var)                    \
do                                                              \
{                                                               \
    (_bind)->vars[_index]=                                      \
        (char *)malloc(LLONG_NUMBER_SIZE+1);                    \
    sprintf((_bind)->vars[_index], LLONG_NUMBER_FMT, _var);     \
} while(0)

#define ORAC_BIND_DOUBLE(_bind, _index, _var)                   \
do                                                              \
{                                                               \
    (_bind)->vars[_index]=(char *)malloc(20+1);                 \
    sprintf((_bind)->vars[_index], "%015.2lf", _var);           \
} while(0)

#define ORAC_BIND_DATE ORAC_BIND_CHAR

/*
 * 数据库环境初始化
 */
extern int	/* 0:成功 -1:失败 */
orac_init();

/*
 * 数据库环境清理
 */
extern void
orac_clean();

/*
 * 完整数据库连接
 */
extern int
orac_connect_ex(
        int conn_index,				/* [IN] 连接索引 */
        char *dbuser,               /* [IN] 用户 */
        char *dbpasswd,             /* [IN] 口令 */
        char *host                  /* [IN] 宿主 */
        );
#define orac_connect(_dbuser,_dbpasswd,_host)  \
orac_connect_ex(0,_dbuser,_dbpasswd,_host)

/*
 * 断开数据库连接
 */
extern int	/* SQLCODE:ORACLE系统错误，常用见ORA_OK等定义 */
orac_disconnect_ex(
        int conn_index				/* [IN] 连接索引 */
        );
#define orac_disconnect() orac_disconnect_ex(0)

/*
 * 事务开始
 */
extern int	/* SQLCODE:ORACLE系统错误，常用见ORA_OK等定义 */
orac_begin_ex(
        int conn_index				/* [IN] 连接索引 */
        );
#define orac_begin() orac_begin_ex(0)

/*
 * 事务提交
 */
extern int	/* SQLCODE:ORACLE系统错误，常用见ORA_OK等定义 */
orac_commit_ex(
        int conn_index				/* [IN] 连接索引 */
        );
#define orac_commit() orac_commit_ex(0)

/*
 * 事务回滚
 */
extern int	/* SQLCODE:ORACLE系统错误，常用见ORA_OK等定义 */
orac_rollback_ex(
        int conn_index				/* [IN] 连接索引 */
        );
#define orac_rollback() orac_rollback_ex(0)

/*
 * 执行非查询SQL语句
 */
extern int	/* SQLCODE:ORACLE系统错误，常用见ORA_OK等定义 */
orac_exec_ex(
        int conn_index,				/* [IN] 连接索引 */
        char *sql,					/* [IN] 执行的SQL语句 */
        DBC_BIND *bind,             /* [IN] 绑定变量结构 */
        int bind_num                /* [IN] 绑定变量数量 */
        );
#define orac_exec(_sql,_bind,_bind_num) \
orac_exec_ex(0,_sql,_bind,_bind_num)

/*
 * 执行查询SQL语句（多线程）
 */
extern int	/* SQLCODE:ORACLE系统错误，常用见ORA_OK等定义 */
orac_query_ex(
        int conn_index,				/* [IN] 连接索引 */
        char *sql,					/* [IN] 执行的SQL语句 */
        DBC_BIND *bind,             /* [IN] 绑定变量结构 */
        int bind_num,               /* [IN] 绑定变量数量 */
        int request_row_num,		/* [IN] 需读取的记录数 */
        DBC_RSET *rset              /* [OUT] 查询结果集
                                       必须由dbc_query_free释放 */
        );
#define orac_query(_sql,_bind,_bind_num,_request_row_num,_result_set)   \
orac_query_ex(0,_sql,_bind,_bind_num,_request_row_num,_result_set)

/*
 * 获取下一序列号
 */
extern int	/* SQLCODE:ORACLE系统错误，常用见ORA_OK等定义 */
orac_sequence_nextval_ex(
        int conn_index,				/* [IN] 连接索引 */
        char *seq,					/* [IN] 序列名 */
        long *nextval         		/* [OUT] 下一序列号 */
        );
#define orac_sequence_nextval(_seq,_nextval)    \
orac_sequence_nextval_ex(0,_seq,_nextval)

__END_DECLS

#endif
